/**
 * js时间工具库
 * 该工具库提供了一系列用于处理时间和日期的实用函数，
 * 功能与 Java 版的 DateUtils 类似，包含日期格式化、解析、计算时间差等功能。
 */

// 定义日期格式常量
const YYYY = "yyyy";
const YYYY_MM = "yyyy-MM";
const YYYY_MM_DD = "yyyy-MM-dd";
const YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
const YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

const PARSE_PATTERNS = [
    "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
    "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
    "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"
];

/**
 * 获取当前 Date 型日期
 * @returns {Date} 当前日期
 */
export function getNowDate() {
    return new Date();
}

/**
 * 获取当前日期, 默认格式为 yyyy-MM-dd
 * @returns {string} 格式化后的日期字符串
 */
export function getDate() {
    return dateTimeNow(YYYY_MM_DD);
}

/**
 * 获取当前时间，格式为 yyyy-MM-dd HH:mm:ss
 * @returns {string} 格式化后的时间字符串
 */
export function getTime() {
    return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
}

/**
 * 获取当前日期时间，默认格式为 yyyyMMddHHmmss
 * @returns {string} 格式化后的日期时间字符串
 */
export function dateTimeNow() {
    return dateTimeNow(YYYYMMDDHHMMSS);
}

/**
 * 按照指定格式获取当前日期时间
 * @param {string} format 日期格式字符串
 * @returns {string} 格式化后的日期时间字符串
 */
export function dateTimeNow(format) {
    return parseDateToStr(format, new Date());
}

/**
 * 按照 yyyy-MM-dd 格式格式化日期
 * @param {Date} date 日期对象
 * @returns {string} 格式化后的日期字符串
 */
export function dateTime(date) {
    return parseDateToStr(YYYY_MM_DD, date);
}

/**
 * 将日期对象按照指定格式转换为字符串
 * @param {string} format 日期格式字符串
 * @param {Date} date 日期对象
 * @returns {string} 格式化后的日期字符串
 */
export function parseDateToStr(format, date) {
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    const hour = String(date.getHours()).padStart(2, '0');
    const minute = String(date.getMinutes()).padStart(2, '0');
    const second = String(date.getSeconds()).padStart(2, '0');

    return format.replace('yyyy', year)
        .replace('MM', month)
        .replace('dd', day)
        .replace('HH', hour)
        .replace('mm', minute)
        .replace('ss', second);
}

/**
 * 将日期字符串按照指定格式解析为日期对象
 * @param {string} format 日期格式字符串
 * @param {string} ts 日期字符串
 * @returns {Date|null} 解析后的日期对象，如果解析失败返回 null
 */
export function dateTime(format, ts) {
    try {
        return new Date(ts);
    } catch (error) {
        return null;
    }
}

/**
 * 日期路径 即年/月/日 如 2018/08/08
 * @returns {string} 日期路径字符串
 */
export function datePath() {
    const now = new Date();
    return parseDateToStr('yyyy/MM/dd', now);
}

/**
 * 日期路径 即年/月/日 如 20180808
 * @returns {string} 日期路径字符串
 */
export function dateTimeStr() {
    const now = new Date();
    return parseDateToStr('yyyyMMdd', now);
}

/**
 * 日期型字符串转化为日期
 * @param {string} str 日期字符串
 * @returns {Date|null} 解析后的日期对象，如果解析失败返回 null
 */
export function parseDate(str) {
    if (!str) {
        return null;
    }
    for (const pattern of PARSE_PATTERNS) {
        try {
            const date = new Date(str);
            if (!isNaN(date.getTime())) {
                return date;
            }
        } catch (error) {
            continue;
        }
    }
    return null;
}

/**
 * 计算两个时间差
 * @param {Date} endDate 结束日期
 * @param {Date} nowDate 开始日期
 * @returns {string} 时间差字符串
 */
export function getDatePoor(endDate, nowDate) {
    const nd = 1000 * 24 * 60 * 60;
    const nh = 1000 * 60 * 60;
    const nm = 1000 * 60;
    const diff = endDate.getTime() - nowDate.getTime();
    const day = Math.floor(diff / nd);
    const hour = Math.floor((diff % nd) / nh);
    const min = Math.floor((diff % nd % nh) / nm);
    return `${day}天${hour}小时${min}分钟`;
}
